package br.com.afi.encoding_converter;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.FileUtils;

import br.com.afi.util.log.Logger;

/**
 * Realiza a conversão de encoding de arquivos.
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 */
public class FileEncodingConverter {
	private static final Logger log = Logger.getLogger( FileEncodingConverter.class );
	private File file;
	private File baseDir;
	private File outputDir;
	private String fromEncoding;
	private String toEncoding;
	
	/**
	 * Cria um conversor que converte o arquivo para o encoding informado. O arquivo será substituído.
	 * 
	 * @param baseDir Diretório base
	 * @param file Arquivo à ser convertido
	 * @param fromEncoding Encoding do arquivo de origem
	 * @param toEncoding Encoding do arquivo de destino
	 */
	public FileEncodingConverter( File baseDir, File file, String fromEncoding, String toEncoding )
	{
		super();
		this.baseDir = baseDir;
		this.file = file;
		this.fromEncoding = fromEncoding;
		this.toEncoding = toEncoding;
	}
	
	/**
	 * Cria um conversor que converte o arquivo para o encoding informado. O novo arquivo será gravado no diretório informado.
	 * 
	 * @param baseDir Diretório base
	 * @param file Arquivo à ser convertido
	 * @param fromEncoding Encoding do arquivo de origem
	 * @param toEncoding Encoding do arquivo de destino
	 * @param outputDir Diretório onde os novos arquivos serão gravados
	 */
	public FileEncodingConverter( File baseDir, File file, String fromEncoding, String toEncoding, File outputDir )
	{
		this( baseDir, file, fromEncoding, toEncoding );
		this.outputDir = outputDir;
	}
	
	private String buildFileName()
	{
		final StringBuilder toFileName = new StringBuilder();
		String path = null;
		if( outputDir != null )
		{
			path = outputDir.getAbsolutePath();
		}
		else
		{
			path = baseDir.getAbsolutePath();
		}
		toFileName.append( path );
		
		final File parent = file.getParentFile();		
		final String subPath = parent.getAbsolutePath().replace( baseDir.getAbsolutePath(), "" );
		
		toFileName.append( subPath );
		toFileName.append( File.separator );
		toFileName.append( file.getName() );

		return toFileName.toString();
	}
	
	/**
	 * Converte o arquivo.
	 * 
	 * @return Arquivo convertido
	 * @throws IOException Lançada quando não for possível gravar o arquivo.
	 */
	@SuppressWarnings("unchecked")
	public File convert() throws IOException
	{
		final List<String> lines = FileUtils.readLines( file, fromEncoding );
		
		
		final File toFile = new File( buildFileName() );
		
		log.info( "Arquivo origem: {0}({1})", file.getAbsolutePath(), fromEncoding );
		log.info( "Arquivo destino: {0}({1})", toFile.getAbsolutePath(), toEncoding );
		
		FileUtils.writeLines( toFile, toEncoding, lines );
		
		log.info( "Conversão realizada." );
		
		return toFile;
	}
}
